package com.qubuyer.business.auth.model

import com.qubuyer.core.framework.BaseModel
import com.qubuyer.core.http.HttpResult
import com.qubuyer.repository.entitys.LoginEntity
import com.qubuyer.repository.entitys.MineCardEntity
import com.qubuyer.repository.entitys.ThirdLoginEntity
import com.qubuyer.repository.entitys.UserEntity
import com.qubuyer.repository.services.ApiService
import com.qubuyer.utils.EnUtil
import com.qubuyer.utils.SessionUtil
import com.qubyer.okhttputil.helper.HttpManager
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File


/**
 * Author: linwg
 * Time: 2021/2/5 0005
 * Description:
 */
class AuthModel : BaseModel() {

    private val api: ApiService by injectApi()

    suspend fun thirdPartLogin(oauth: String, openId: String): HttpResult<ThirdLoginEntity?> {
        return api.thirdPartLogin(oauth, openId).also { if (it.ok()) saveToken(it.data?.token) }
    }

    suspend fun getCode(phone: String): HttpResult<String?> {
        return api.verifySms(phone)
    }

    suspend fun verifySms(phone: String): HttpResult<String?> {
        return api.verifySms(phone)
    }

    suspend fun updatePhoneStepOne(phone: String, code: String): HttpResult<String?> {
        return api.setMobileOne(phone, code)
    }

    suspend fun updatePhoneStepTwo(phone: String, code: String): HttpResult<String?> {
        return api.setMobileTwo(phone, code).also {
            if (it.ok()) {
                val userInfo = SessionUtil.getInstance().userInfo
                userInfo.mobile = phone
                SessionUtil.getInstance().saveUserInfo(userInfo)
            }
        }
    }

    suspend fun login(phone: String, password: String): HttpResult<LoginEntity?> {
        return api.login(phone, EnUtil.encrypt(password)).also { if (it.ok()) saveToken(it.data?.token) }
    }

    suspend fun phoneLogin(phone: String, code: String): HttpResult<LoginEntity?> {
        return api.mobileLogin(phone, code).also { if (it.ok()) saveToken(it.data?.token) }
    }

    suspend fun register(phone: String, code: String, password: String, inviteCode: String): HttpResult<LoginEntity?> {
        return api.doRegister(phone, EnUtil.encrypt(password), code, inviteCode).also { if (it.ok()) saveToken(it.data?.token) }
    }

    suspend fun forgetPassword(phone: String, code: String, password: String, password2: String): HttpResult<String?> {
        val encrypt = EnUtil.encrypt(password)
        return api.forgetPassword(phone, code, encrypt, encrypt)
    }

    suspend fun bindPhone(phone: String, code: String, openId: String, oauth: String): HttpResult<LoginEntity?> {
        return api.bind(phone, code, oauth, openId).also { if (it.ok()) saveToken(it.data?.token) }
    }

    suspend fun codeBind(oauth: String, openId: String): HttpResult<MineCardEntity?> {
        return api.codeBind(oauth, openId)
    }

    suspend fun alipayInitApp(): HttpResult<String?> {
        return api.alipayInitApp()
    }

    suspend fun userInfo(): HttpResult<UserEntity?> {
        return api.userInfo().also { if (it.ok()) SessionUtil.getInstance().saveUserInfo(it.data) }
    }

    suspend fun setPwd(token: String, inviteCode: String, pwd: String, pwdSecond: String): HttpResult<LoginEntity?> {
        val encrypt = EnUtil.encrypt(pwd)
        return api.setPassword(token, inviteCode, password = encrypt, password2 = encrypt).also { if (it.ok()) saveToken(it.data?.token) }
    }

    private fun saveToken(token: String?) {
        SessionUtil.getInstance().token = token
        HttpManager.getInstance().init(token, SessionUtil.getInstance().tokenOverduedListener)
    }

    suspend fun logout(): HttpResult<String?> {
        return api.logout().also { if (it.ok()) SessionUtil.getInstance().loginOut() }
    }

    suspend fun updateHeadImage(file: File): HttpResult<String?> {
        val requestFile = file.asRequestBody("image/jpg".toMediaTypeOrNull());
        val body = MultipartBody.Part.createFormData("head", file.name, requestFile);
        return api.updateHeadImage(body)
    }

    suspend fun userInfoEdit(nickname: String): HttpResult<String?> {
        return api.userInfoEdit(nickname).also {
            if (it.ok()) {
                val userInfo = SessionUtil.getInstance().userInfo
                userInfo.nickname = nickname
                SessionUtil.getInstance().saveUserInfo(userInfo)
            }
        }
    }
}